#ifndef KLONDIKE_H
#define KLONDIKE_H

#include "cardspot.h"
#include "cardengine.h"

class Deck : public CardSpot
{
public:
    enum { Type = 9 };

    Deck()
        : CardSpot(Type, "Deck")
    {}

    virtual bool canDraw() const
    {
        return data.cards.size() > 0;
    }
};

class Foundation : public CardSpot
{
public:
    enum { Type = 10 };
    Foundation(Card::Suit s)
        : CardSpot(Type, "Foundation"), suit(s)
    {}

    virtual bool canDrop(const Card *card) const
    {
        if (card->suit() == suit) {
            const int rank = data.cards.size() == 0 ? 1 : (*data.cards.end())->rank() + 1;
            if (card->rank() == rank)
                return true;
        }
        return false;
    }

    const Card::Suit suit;
};

class Tableau : public CardSpot
{
public:
    enum { Type = 11 };
    Tableau()
        : CardSpot(Type, "Tableau")
    {}

    virtual bool canDrop(const Card *card) const
    {
        if (data.cards.size() == 0)
            return card->rank() == 13;

        const int rank = (*data.cards.end())->rank() - 1;
        return card->rank() == rank && card->isRed() != (*data.cards.end())->isRed();
    }
};


class Klondike : public CardEngine
{
public:
    Klondike()
        : CardEngine("Klondike", Type_Klondike)
    {
        topLayout = new RenderObjectLayout(RenderObjectLayout::HorizontalBox);
        deck = new Deck;
        topLayout->addRenderObject(deck);
        topLayout->addSpacer();
        for (int i=0; i<Card::SuitCount; ++i) {
            foundations[i] = new Foundation(static_cast<Card::Suit>(i));
            Rectangle rect(i * 55, 10, 50, 100);
            foundations[i]->setGeometry(rect);
            cardSpots.push_back(foundations[i]);
        }
        for (int i=0; i<7; ++i) {
            tableau[i] = new Tableau;
            cardSpots.push_back(tableau[i]);
            Rectangle rect(i * 55, 10, 50, 100);
            tableau[i]->setGeometry(Rectangle(i * 55, 120, 50, 100));
        }
        reset();
        for (int i=0; i<7; ++i) {
            for (int j=0; j<i+1; ++j) {
                Card *c = pop_deck();
                if (j == i)
                    c->flip(Card::FaceUp);
                tableau[i]->push_back(c);
            }
        }
    }

    ~Klondike()
    {
    }

    void init()
    {
        reset();
    }

    virtual std::vector<Card*> grabCard(Card *card) const
    {
        std::vector<Card*> result;
        if (card->face() == Card::FaceUp) {


        }
        return result;
    }

    Deck *deck;
    RenderObjectLayout *topLayout, *tableayLayout;
    Foundation *foundations[Card::SuitCount];
    Tableau *tableau[7];
};

#endif
